package com.epi.two;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.*;
import java.net.URL;

/**
 * DOM 解析 XML 示例
 *
 * @author dxy
 * @version 1.0
 */
public class XmlDemo {

    public static void main(String[] args) throws Exception {
//        domDemo();
        streamDemo();

    }

    private static void streamDemo() throws XMLStreamException, FileNotFoundException {
        String filePath = "src/main/resources/data/person.xml";

        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream(filePath));

        String currentElement = null;

        while (reader.hasNext()) {
            int event = reader.next();

            switch (event) {
                case XMLStreamConstants.START_ELEMENT:
                    currentElement = reader.getLocalName();
                    break;

                case XMLStreamConstants.CHARACTERS:
                    String text = reader.getText().trim();
                    if (!text.isEmpty() && currentElement != null) {
                        System.out.println(currentElement + ": " + text);
                    }
                    break;

                case XMLStreamConstants.END_ELEMENT:
                    currentElement = null;
                    break;
            }
        }

        reader.close();
    }

    private static void domDemo() {
        try {
            // 1. 构建解析器
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true); // 关键
            DocumentBuilder builder = factory.newDocumentBuilder();

            // 2. 解析文档为 DOM 树
//            var doc = getDocument(builder);
            var doc = builder.parse(new File("src/main/resources/data/easy.xml"));
            NodeList font = doc.getElementsByTagName("font");
            Node item = font.item(0);
            Element element = (Element) item;
            NodeList childNodes = element.getChildNodes();

            for (int i = 0; i < childNodes.getLength(); i++) {
                Node childNode = childNodes.item(i);
                short type = childNode.getNodeType();

                // 过滤掉空白的文本节点，避免输出无意义的换行符和空格
                if (type == Node.TEXT_NODE && childNode.getTextContent().trim().isEmpty()) {
                    continue;
                }

                System.out.println("Node " + i + "【" + childNode.getNodeName() + "】");
                System.out.println("Type: " + type + " (" + nodeTypeName(type) + ")");
                System.out.println("Content:[" + childNode.getTextContent() + "]");
                System.out.println("======");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String nodeTypeName(short nodeType) {
        return switch (nodeType) {
            case Node.ELEMENT_NODE -> "ELEMENT_NODE";
            case Node.ATTRIBUTE_NODE -> "ATTRIBUTE_NODE";
            case Node.TEXT_NODE -> "TEXT_NODE";
            case Node.CDATA_SECTION_NODE -> "CDATA_SECTION_NODE";
            case Node.COMMENT_NODE -> "COMMENT_NODE";
            case Node.PROCESSING_INSTRUCTION_NODE -> "PROCESSING_INSTRUCTION_NODE";
            case Node.DOCUMENT_NODE -> "DOCUMENT_NODE";
            case Node.DOCUMENT_TYPE_NODE -> "DOCUMENT_TYPE_NODE";
            default -> "OTHER";
        };
    }


    private static Document getDocument(DocumentBuilder builder) throws SAXException, IOException {
        // 1. 从文件解析
        File xmlFile = new File("src/main/resources/data/test.xml");
        Document docFromFile = builder.parse(xmlFile);

        // 2. 从 URL 解析
        URL xmlUrl = xmlFile.toURI().toURL();
        Document docFromUrl = builder.parse(xmlUrl.openStream());

        // 3. 从 InputStream 解析（这里以类加载器加载资源为例）
        try (InputStream is = XmlDemo.class.getClassLoader()
            .getResourceAsStream("data/test.xml")) {
            Document docFromStream = builder.parse(is);
        }

        return docFromFile;
    }
}
